/*
#Copyright (c) 2013, Philippe Bordron <philippe.bordron@gmail.com>
#
# This file is part of SIPPER.
#
# DCC is free software: you can redistribute it and/or modify
# it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# DCC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU LESSER GENERAL PUBLIC LICENSE for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# along with SIPPER.  If not, see <http://www.gnu.org/licenses/>
*/
package combi.wip.sipper.modules;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

//import org.jgrapht.ext.GmlExporter;
import org.jgrapht.DirectedGraph;
import org.jgrapht.ext.IntegerNameProvider;
import org.jgrapht.graph.DefaultEdge;

import combi.wip.sipper.io.dot.DOTColorExporter;
import combi.wip.sipper.io.dot.VertexAlternateNameProvider;

import combi.wip.utils.OrdrePartiel;
import combi.wip.utils.OrdrePartielInclusionSetString;
import combi.wip.graph.Treilli;
import combi.utils.Couple;


public class InclusionChemins {

	//private static String pathPrefix = "./ecocyc - ALL-CHORISMATE-PWY - 53/";
	//private static String pathPrefix = System.getProperty("user.home") + "/Data/Chili/meta_reaction/";
	//private static String pathPrefix = System.getProperty("user.home") + "/Data/Chili/Metacyc/ecoli/Gint_15.0/";
	//private static String pathPrefix = System.getProperty("user.home") + "/Data/Chili/Metacyc/afer243159/Gint/";




	//private static String ressources = System.getProperty("user.home") + "/Data/Chili/Metacyc/ecoli/15.0/data/";
	//private static String ressources =  System.getProperty("user.home") + "/Data/Chili/Metacyc/afer243159/14.1/data/";
	//private static String ressources = System.getProperty("user.home") + "/Data/Chili/export/";
	//private static String pathPrefix = "./data/";
	private static int k =Integer.MAX_VALUE;
	//private static int k =10;
	//private static double taux = 0.7;
	//private static boolean bestSubSet = true; // Meilleur sous ensemble de kSIPs en accord avec la mesure
	//private static int bestK = 0; // Nb de kSIPs à sélectionner; =< 0 indique la meilleur des toutes les possibilités.

	public static void main(String[] args) {
		//String outmodbestSubSet ="";
		//if (bestSubSet)
		//{
		//	outmodbestSubSet = "best_" + bestK + "_From_";
		//}
		String fileIn = args[0];
		String fileOutTreilli = args[1];
		String fileOutLeaves = args[2];
		//String fileIn = pathPrefix + "cheminsTraduitsFiltre_"+ taux + "_" +outmodbestSubSet+k+"ksp.txt";
		//String fileIn = pathPrefix + "cheminDecontract.txt";
		//String fileOut = pathPrefix + "infoResultat"+ k +"ksp.txt";
		//String fileOutReactions = pathPrefix + "infoResultatReactions"+ k +"ksp.txt";
		//String fileOutGenes = pathPrefix + "infoResultatGenes"+ k +"ksp.txt";
		//String fileBase = ressources + "genesPos.txt";
		//String fileEquiv = pathPrefix + "redondances"+ k +".txt";

		//String dirIn = "/Users/bordronphilippe/Documents/Th�se/GOclusters/pvalue10";
		//String dirIn = pathPrefix+"/pvalue"+ k ;

		try{
			Matcher m;
			//String dd = "(?:[0-9]+(?:\\.[0-9]+)?)";
			String recoReaction = "(?:" +"\\S+" + ")";
			String beginBloc = "(?:(" + recoReaction + ")->(" + recoReaction + "))";
			//String geneName = "(?:(" + flottant + ")\t(" + flottant + ")\t(" + flottant + ")\t" +"\\[\\{\\((?:\\+|-)b[0-9]{4}:([^,:]+),.+:([^,:]+),R[0-9]{5}\\),?\\},?\\]" + ")"; //gloutonnerie
			//String geneName = "(?:"+ "(?:" + ":([^,]+),(" + recoReaction  + ")\\))" + ")"; //gloutonnerie limit�e
			//String geneName = "(?:"+ "(?:" + "\\([+-]?([^:]+)[^,]*,(" + recoReaction  + ")\\))" + ")"; //gloutonnerie limit�e
			String geneName = "(?:"+ "(?:" + "\\(([^:]+):(" + recoReaction  + ")\\))" + ")"; //gloutonnerie limit�e

			Pattern reco = Pattern.compile(beginBloc);
			Pattern recoGeneName = Pattern.compile(geneName);

			//chargement des �quivalences de clusters de genes pour la pvalue.
			BufferedReader in;
			String ch;
			Couple<String, String> id = null;
			in = new BufferedReader (new FileReader (fileIn));

			//associate to each ksip (deb,fin) the list of the gene or reaction or full label.
			Map<Couple<String, String>, List<String>> labelsCh = new HashMap<Couple<String, String>, List<String>>();
			Map<List<String>, String> labels = new HashMap<List<String>, String>();

			//OrdrePartiel<List<String>> orderP = new OrdrePartielInclusionChemins();
			OrdrePartiel<List<String>> orderP = new OrdrePartielInclusionSetString();
			Treilli<List<String>> t = new Treilli<List<String>>(orderP);

			List<String> chemin = new LinkedList<String>();
			int limiteK = 0;
			int limiteMax = k;
			int cpt = 0;
			Map<List<String>, String> sauvFic = new HashMap<List<String>,String>();
			String sauvBloc = "";
			while ((ch = in.readLine()) != null)
			{
				try
				{
					if (ch.isEmpty()) //fini
					{
						cpt++;
						//System.err.println("ch.isEmpty()");
						if (chemin.size() != 0)
						{
							System.err.println(cpt + " : " + id);
							labelsCh.put(id, chemin);
							if (t.add(chemin))
							{	
								labels.put(chemin,new String());
							}
							labels.put(chemin, labels.get(chemin) + id.getFirst().toString()+"->"+id.getSecond().toString() +"\\\\n");
							sauvFic.put(chemin, sauvBloc);

						}
						//raz
						id = null;
						limiteK = -1;
						chemin = new LinkedList<String>();
						sauvBloc = "";
					}
					if (limiteK <= limiteMax)
					{
						m = reco.matcher(ch);
						//reconnaissance des Rx -> Ry
						if (m.find())
						{
							id = new Couple<String, String>(new String(m.group(1)),new String(m.group(2)));
							//System.err.println(id);
						}
						System.err.println(id);
						
						m = recoGeneName.matcher(ch);
						while(m.find())
						{
							Couple<String, String> newCouple = new Couple<String, String> (new String(m.group(1)), new String (m.group(2)));
							System.err.println(newCouple);
							chemin.add(newCouple.toString());
						}
						limiteK++;
						sauvBloc =sauvBloc + ch + "\n";
					}
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
				//enregistrement des valeurs extraites dans structure.
			}
			if (chemin.size() != 0)
			{
				System.err.println(id);
				labelsCh.put(id, chemin);
				if (t.add(chemin))
				{	System.err.println(id);
				labels.put(chemin,new String());
				}
				labels.put(chemin, labels.get(chemin) + id.getFirst().toString()+"->"+id.getSecond().toString() +"\\\\n");

			}
			in.close();
			System.err.println("Exportation treillis");

			//System.err.println(t.getTreillis());
			for (Entry<List<String>, String> entry : labels.entrySet())
			{
				entry.setValue("\"" + entry.getValue().substring(0, entry.getValue().lastIndexOf("\\")-1) + "\"");
			}

			labels.put(orderP.getFakeRoot(), "\"\"");
			//GmlExporter<List<String>, DefaultEdge> graphML = new GmlExporter<List<String>, DefaultEdge>();
			DOTColorExporter<List<String>, DefaultEdge> graphDOT = new DOTColorExporter<List<String>, DefaultEdge>(new IntegerNameProvider<List<String>>(), new VertexAlternateNameProvider<List<String>>(labels),null);
			try {
				graphDOT.setRankDir("LR");
				DirectedGraph<List<String>, DefaultEdge> g = t.getTreillis();
				g.removeVertex(orderP.getFakeRoot());
				graphDOT.export(new BufferedWriter(new FileWriter(fileOutTreilli)), g);
				//graphDOT.export(new BufferedWriter(new FileWriter(pathPrefix + "treillis_"+outmodbestSubSet+k+"ksp" + ".dot")), t.getTreillis());
				//graphML.export(new BufferedWriter(new FileWriter(pathPrefix + "treillis_"+outmodbestSubSet+k+"ksp" + ".gml")), t.getTreillis());
				//exportation des feuilles du treillis.


			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}


			//Exportation des feuilles.
			System.err.println("Exportation des feuilles du treillis");
			//System.err.println(sauvFic);
			BufferedWriter out;
			try {
				out = new BufferedWriter(new FileWriter(fileOutLeaves));
				//out = new BufferedWriter(new FileWriter(pathPrefix + "cheminsCouvrants_feuille_"+outmodbestSubSet+k+"ksp.txt"));
				//System.err.println(t.getTreillis().vertexSet());
				for (List<String> v :t.getTreillis().vertexSet())
				{
					//System.out.println(t.getTreillis().outDegreeOf(v));
					if (t.getTreillis().outDegreeOf(v) == 0)
					{
						//feuille
						out.write(sauvFic.get(v) + "\n");
					}
				}
				out.close();
			}catch(Exception e){
				e.printStackTrace();
				System.exit(1);
			}

		}catch(Exception e){
			e.printStackTrace();
			System.exit(1);
		}

		finally{

		}
	}


}
